const fs = require('fs');
const path = require('path');
const os = require('os')

// const node_modules = path.resolve(__dirname, 'node_modules');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
const HappyPack = require('happypack');
const lessToJs = require('less-vars-to-js');
// const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
// 进度条
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
// 分离css，extract-text-webpack-plugin 的替代包
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 警告过滤
const FilterWarningsPlugin = require('webpack-filter-warnings-plugin'); 
// css压缩、优化、去重
const optimizeCss = require('optimize-css-assets-webpack-plugin'); 
// js 压缩，使用这个插件因为使用css压缩情况下，mode=production不会对js压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 
// 这个压缩才支持es6
const TerserPlugin = require('terser-webpack-plugin');
// 二次构建优化
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
// 导入路径校验大小写
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');

const pkgJson = require('./package');

// 拿到系统CPU的最大核数，happypack 将编译工作灌满所有线程
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })

// 主题
const app_theme = lessToJs(fs.readFileSync(path.join(__dirname, './src/theme/theme.less'), 'utf8'));

const svgDirs = [
  require.resolve('antd-mobile').replace(/warn\.js$/, ''), // 1. 属于 antd-mobile 内置 svg 文件
  // path.resolve(__dirname, 'src/my-project-svg-foler'),  // 2. 自己私人的 svg 存放目录
];

const dev_stg = (function(e){
  let obj = {
    dev:{
      extractText: true,//是否禁用样式抽离
      chunks: ['common.js', 'index'],//首页需要导入的文件
      devtool: "cheap-module-eval-source-map",//制定文件格式为最快速文件格式
      debug: true//开启debug模式
    },
    stg:{
      extractText: true,//是否禁用样式抽离
      chunks: ['common.js', 'index','index.css'],//首页需要导入的文件
      devtool: 'nosources-source-map',//制定文件格式为最小体积文件格式
      debug: false//关闭debug模式
    }
  }
  if(e === 'loc'){
    return obj['dev'];
  }else{
    return obj['stg'];
  }
})(process.env.NODE_ENV);

//配置文件
const config = {
  // webpack4 mode
  mode: String(process.env.NODE_ENV) !== 'loc' ? 'production' : 'development',
  entry: {
    index: './src/app/index.js',
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name]-v_[hash:8].js',
    publicPath: 'loc' === '' + process.env.NODE_ENV ? '' : pkgJson.config['' + process.env.NODE_ENV].publicPath
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'happypack/loader?id=js',
        include: path.join(__dirname, 'src'),
        exclude: /(node_modules)/
      },
      {
        test: /\.(less|css)$/,
        use: [
          String(process.env.NODE_ENV) === 'loc' ? 'style-loader' : MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            // options: {
            //   importLoaders: 1,
            //   modules: {
            //     // auto: (resourcePath) => resourcePath.endsWith('.module.less'),
            //     localIdentName: '[name]__[local]--[hash:base64:5]',
            //     context: path.resolve(__dirname, 'src'),
            //   },
            // },
          },
          'postcss-loader', 
          {
            loader: 'less-loader', 
            query: {
              modifyVars: app_theme,
            javascriptEnabled: true,
            }
          }
        ]
      },
      {
        test: /\.(png|jpg|gif|md|ttf|eot|otf)$/i,
        use: ['url-loader?limit=10000&name=[md5:hash:base64:10].[ext]']
      },
      {
        test: /\.(svg)$/i,
        use: 'svg-sprite-loader',
        include: svgDirs, // 把 svgDirs 路径下的所有 svg 文件交给 svg-sprite-loader 插件处理
      },
    ],
  },
  resolve: {
    extensions: ['.web.js', '.js', '.jsx', '.json', '.css', '.less'],
    modules: ['node_modules', path.join(__dirname, 'src')],
    alias: {
      'widget': path.join(__dirname, 'src/app/widget'),
      'util': path.join(__dirname, 'src/app/util'),
      'biz': path.join(__dirname, 'src/app/biz'),
      'config': path.join(__dirname, 'src/app/config'),
      'assets': path.join(__dirname, 'src/app/assets'),
      'pubBiz': path.join(__dirname, 'src/app/pubBiz'),
    }
  },
  devtool: dev_stg.devtool,
  plugins: [
    new CaseSensitivePathsPlugin(),
    // 构建进程插件
    new ProgressBarPlugin(),
    // 提取css
    new MiniCssExtractPlugin({
      filename: "styles/[name].[hash:8].css",
      chunkFilename: "styles/[id].[hash:8].css"
    }),
    // 过滤min-css-extract-plugin 插件爆出的conflict warning
    new FilterWarningsPlugin({
      exclude: /mini-css-extract-plugin[^]*Conflicting order between:/,
    }),
    
    // 这个插件可以使二次构建速度明显提升
    new HardSourceWebpackPlugin({
      // environmentHash被用来确定这一点。如果散列与先前的构建不同，则将使用新的缓存
      environmentHash: {
        root: process.cwd(),
        directories: [],
        files: ['package-lock.json', 'yarn.lock']
      }
    }), 
    new webpack.HotModuleReplacementPlugin(),
    new LodashModuleReplacementPlugin(),
    // copy 静态文件
    new CopyWebpackPlugin([
      { from: path.resolve(__dirname, './src/app/assets'), to: 'assets' },
    ]),
    // 定义全局变量
    new webpack.DefinePlugin({
      "ENV": JSON.stringify(process.env.NODE_ENV),
      "CDN_BASE": JSON.stringify(pkgJson.config['' + process.env.NODE_ENV].CDN_BASE),
    }),
     // css压缩
    new optimizeCss({
      assetNameRegExp: /\.style\.css$/g,
      cssProcessor: require('cssnano'),
      cssProcessorOptions: { discardComments: { removeAll: true } },
      canPrint: true
    }),
    // 处理html模板
    new HtmlWebpackPlugin({
      // chunks: dev_stg.chunks,
      inject: 'body',
      // chunksSortMode: 'manual',
      // excludeChunks:['common.js','index'],
      showErrors: true,
      W_ENV: process.env.NODE_ENV,
      publicPath: pkgJson.config['' + process.env.NODE_ENV].publicPath,
      hash: true,
      template: 'src/index.html',
    }),
    // babel转译
    new HappyPack({
      id: 'js',
      threadPool: happyThreadPool,
      loaders: [{
        loader: 'babel-loader',
        query: {
          cacheDirectory: true, // 缓存
          presets: ['es2015', 'react', 'stage-1'],
          plugins: [
            "transform-runtime",
            "transform-decorators-legacy",
            "transform-class-properties", ["import", { libraryName: "antd-mobile", style: true }]
          ]
        }
      }]
    }),
  ],
  optimization: {
    // 提取公共模块依赖，不必再用dll
    splitChunks: {
      chunks: "all", // 所有的 chunks 代码公共的部分分离出来成为一个单独的文件
    },
    // 压缩 mode = productin 才会执行
    minimizer: [
      // js压缩
      new TerserPlugin({
        cache: true, // Boolean/String,字符串即是缓存文件存放的路径
        parallel: true, // 启用多线程并行运行提高编译速度
        sourceMap: true
      }),
      // css压缩
      new optimizeCss({}),
    ],
  },
  devServer :{
    disableHostCheck: true,
    host: '0.0.0.0',
    port: 9095
  }
};

module.exports = config;
